﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;

public class LayerObject : ObjectBase
{

    public nLayerData _layerData;

    public LayerObject(nLayerData ld, int layer) : 
        base(ld._layer_cell_name, layer)
    {
        _layerData = ld;

        //_Height = ld._Pos.y;

        //_Object.transform.position = _layerData._Pos;
    }

    nRectangleVBOData _data = null;

    public override void Load()
    {
        base.Load();

        GameObject.Destroy(_bc2d);

        //
        _dc.ReBorder(_layerData._Width, _layerData._Height);
        _dc.RefreshBorder();

        //
        _rgc = _Object.AddComponent<RhombusGridComponent>();

        switch (_layerData._layer_type)
        {
            case nLayerType.Null:
            case nLayerType.Rhombus:
                Debug.LogError("nLayerType == null || Rhombus");
                break;
            case nLayerType.Rectangle:
                _data = new nRectangleVBOData(_layerData._Width,
                                                _layerData._Width / ZoneCfg.RhombusFactor,
                                                _layerData._Width,
                                                _layerData._Height);
                _rgc.FormatRectangle(_data);
                break;
        }

        InitBlocks();
    }

    public override bool Save()
    {
        _layerData._grids_block = _grid_blocks;

        return true;
    }

    public override void Unload()
    {
        _SR.sprite = null;

        base.Unload();
    }


    /// <summary>
    /// 返回最接近的点
    /// </summary>
    /// <param name="worldposRhombus">单位里一个点的世界坐标</param>
    public int GetClosePointOrder(Vector3 worldposRhombus, nRhombusVBOData vbodata)
    {
        int _close_order = -1;

        //  最接近的坐标
        Vector3 nearestpos = worldposRhombus;

        for (int i = 0; i < _rgc._grids.Length; ++i)
        {
            nRhombusVBOData data = new nRhombusVBOData(ZoneCfg.RhombusMin, ZoneCfg.RhombusMin / ZoneCfg.RhombusFactor, _rgc._grids[i]);

            if (VBOUtil.PolygonIsContainPoint(nearestpos, data._vertexts))
            {
                _close_order = i;

                break;
            }
        }

        return _close_order;
    }


    public void SetEnable(bool flag)
    {
        if (_rgc._blocks == null)
            return;

        for (int i = 0; i < _grid_blocks.Length; ++i)
        {
            RhombusBlockComponent rbc = _rgc._blocks[i].GetComponent<RhombusBlockComponent>();
            rbc.SetEnable(flag);
        }
    }

    /// <summary>
    /// 获取最近的那个店的序号
    /// </summary>
    /// <param name="order"></param>
    public Vector3 GetClosePointRhombus(int order, nRhombusVBOData vbodata)
    {
        float offset = vbodata._left.y - (ZoneCfg.RhombusMin / ZoneCfg.RhombusFactor / 2);

        Vector3 pos = _rgc._grids[order] - new Vector3(0, offset, 0);

        return pos;
    }

    /// <summary>
    /// 当前点是否可以放置
    /// </summary>
    /// <param name="order"></param>
    /// <param name="vbodata"></param>
    /// <returns></returns>
    public bool IsCanDone(int beginorder, nRhombusVBOData vbodata)
    {
        if (beginorder < 0)
            return false;

        if (beginorder > _rgc._grids.Length - 1)
            return false;

        List<int> orders = GetRelationGrids(beginorder, _rgc._grids[beginorder], vbodata);

        _dc.RefreshDescription("orders 0: " + orders[0].ToString());

        for (int i = 0; i < orders.Count; ++i)
        {
            int o = orders[i];

            if (_grid_blocks[o] != 0)
                return false;
        }

        if (_layerData._is_Collider)
        {
            _rgc.FreshBlock(orders, ref _grid_blocks);
        }

        return true;
    }

    /// <summary>
    /// 更新地块
    /// </summary>
    /// <param name="beginorder"></param>
    /// <param name="vbodata"></param>
    public void FreshBlock(int beginorder, nRhombusVBOData vbodata)
    {
        List<int> orders = GetRelationGrids(beginorder, _rgc._grids[beginorder], vbodata);

        //  刷新阻挡状态
        _rgc.FreshBlock(orders, ref _grid_blocks);

    }

    /// <summary>
    /// 确定占用这些碰撞点
    /// </summary>
    /// <param name="beginorder"></param>
    /// <param name="vbodata"></param>
    public List<int> SetDone(int beginorder, nRhombusVBOData vbodata)
    {
        Vector3 posRhombus = _rgc._grids[beginorder];

        List<int> orders = GetRelationGrids(beginorder, posRhombus, vbodata);

        for (int i = 0; i < _grid_blocks.Length; ++i)
        {
            int status = -1;
            if (orders.Contains(i))
            {
                _grid_blocks[i] = 1;
                status = 1;
            }
            else
            {
                status = 0;
            }

            if (_grid_blocks[i] == 1)
                status = 1;

            if (_rgc._blocks != null)
            {
                RhombusBlockComponent rbc = _rgc._blocks[i].GetComponent<RhombusBlockComponent>();
                rbc.SetStatus(status);
            }
        }


        return orders;
    }

    /// <summary>
    /// 取消站用点 别设置为可用状态
    /// </summary>
    /// <param name="beginorder"></param>
    /// <param name="vbodata"></param>
    public void CancelDone(int[] _groud_grid_blocks)
    {
        if (_groud_grid_blocks == null)
        {
            return;
        }

        for (int i = 0; i < _groud_grid_blocks.Length; ++i)
        {
            int o = _groud_grid_blocks[i];

            _grid_blocks[o] = 0;

            if (_rgc._blocks != null)
            {
                RhombusBlockComponent rbc = _rgc._blocks[o].GetComponent<RhombusBlockComponent>();
                rbc.SetStatus(2);

            }
        }
    }

    public void SetDone(List<int> _groud_grid_blocks)
    {
        if (_groud_grid_blocks == null)
        {
            return;
        }

        for (int i = 0; i < _groud_grid_blocks.Count; ++i)
        {
            int o = _groud_grid_blocks[i];

            _grid_blocks[o] = 1;

            if (_rgc._blocks != null)
            {
                RhombusBlockComponent rbc = _rgc._blocks[o].GetComponent<RhombusBlockComponent>();
                rbc.SetStatus(1);

            }
        }
    }

    #region Block
    public int[] _grid_blocks = null;

    public void InitBlocks()
    {
        //  数据
        int len = _rgc._grids.Length;

        List<int> _number = new List<int>(len);
        for (int i = 0; i < len; ++i)
            _number.Add(0);

        _grid_blocks = _number.ToArray();

        /// 物体层不是0才创建材质
        if (_layerData._is_Collider)
        {
            //  对象
            _rgc.FormatRectangleMesh();

            if (_rgc._blocks != null)
            {
                for (int i = 0; i < _rgc._blocks.Length; ++i)
                {
                    RhombusBlockComponent rbc = _rgc._blocks[i].GetComponent<RhombusBlockComponent>();
                    rbc.SetStatus(0);
                }
            }
        }
    }

    /// <summary>
    /// 获取beginorder开始的和VBo先关的几个网格
    /// </summary>
    /// <param name="beginorder"></param>
    /// <param name="posRhombus"></param>
    /// <param name="vbodata"></param>
    /// <returns></returns>
    public List<int> GetRelationGrids(int beginorder, Vector3 posRhombus, nRhombusVBOData vbodata)
    {
        List<Vector3> list = new List<Vector3>(vbodata._grids.Length);

        {
            //  找到相近的几个点
            float n = vbodata._h_Diagonal / ZoneCfg.RhombusMin;

            int count = Mathf.RoundToInt(n);

            int col = 0;
            int row = 0;

            float sec_dis = vbodata._dis / count;

            for (row = 0; row < count; ++row)
            {
                for (col = 0; col < count; ++col)
                {
                    Vector3 x = vbodata._dir_dn * row * sec_dis;
                    Vector3 y = vbodata._dir_up * col * sec_dis;
                    Vector3 pos = x + y + posRhombus;

                    list.Add(pos);
                }
            }
        }

        int _close_order = 0;
        float _close_dis = float.MaxValue;

        List<int> orders = new List<int>();
        {
            //  找到对应的序号
            for (int i = 0; i < list.Count; ++i)
            {
                _close_order = 0;
                _close_dis = float.MaxValue;

                for (int j = 0; j < _rgc._grids.Length; ++j)
                {
                    float x_delta = Mathf.Abs(list[i].x - _rgc._grids[j].x);
                    float y_delta = Mathf.Abs(list[i].y - _rgc._grids[j].y);

                    if ((x_delta < ZoneCfg.RhombusMin / 2) &&
                            (y_delta < ZoneCfg.RhombusMin / ZoneCfg.RhombusFactor / 2))
                    {
                        _close_order = j;
                        break;
                    }
                }

                orders.Add(_close_order);
            }

        }

        return orders;
    }
    #endregion Block
}
